package com.example.tokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 自定义全局过滤器，用于在Spring Cloud Gateway中实现JWT认证。
 */
@Slf4j
@Component
public class JwtAuthenticationFilter implements GlobalFilter, Ordered {

    /**
     * 用于从请求头中提取的Authorization字段的名称。
     */
    private static final String AUTH_TOKEN = "Authorization";

    /**
     * 登录请求的路径，用于免于Token验证。
     */
    private static final String LOGIN_PATH = "/api/auth/login";

    /**
     * 注册请求的路径，用于免于Token验证。
     */
    private static final String REGISTER_PATH = "/api/auth/register";

    /**
     * 注入JwtTokenUtil，用于Token的验证。
     */
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    /**
     * 实现GlobalFilter接口的filter方法，对请求进行过滤。
     *
     * @param exchange 当前请求的上下文信息
     * @param chain 过滤器链，用于执行下一个过滤器或继续处理请求
     * @return 一个Mono<Void>对象，表示异步操作的完成
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();

        // 如果是登录或注册请求，直接放行，不需要Token验证
        if (path.startsWith(LOGIN_PATH) || path.startsWith(REGISTER_PATH)) {
            log.info("登录或注册请求，无需Token验证");
            return chain.filter(exchange);
        }

        // 从请求头中获取Token
        String token = request.getHeaders().getFirst(AUTH_TOKEN);
        System.out.println("进入拦截验证");
        System.out.println("token:" + token);

        if (token == null || !token.startsWith("Bearer ")) {
            // 如果Token不存在或格式不正确，返回401错误
            System.out.println("格式不正确");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
//        注意！下面这个条件仅在测试环境使用！生产环境需要注释或者删除
        else if
        (token.equals("Bearer testToken")) {
            return chain.filter(exchange);
        }
        // 提取Token字符串
        token = token.substring(7);
        System.out.println("token:" + token);
        // 验证Token的有效性
        if (!jwtTokenUtil.validateJwtToken(token)) {
            System.out.println("token失效了！");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        System.out.println("验证成功！");
        // 如果Token验证通过，继续执行过滤器链中的下一个过滤器
        return chain.filter(exchange);
    }

    /**
     * 实现Ordered接口的getOrder方法，定义过滤器的执行顺序。
     *
     * @return 过滤器的顺序值，值越小越先执行
     */
    @Override
    public int getOrder() {
        return -1; // 确保这个过滤器在路由之前执行
    }
}
